#!/usr/bin/env python

"""
Simple built-in classes and functions.

Copyright (C) 2005, 2006 Paul Boddie <paul@boddie.org.uk>

This software is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public
License along with this library; see the file LICENCE.txt
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

--------

The docstring annotations have the following meanings:

    NAME            Indicates a "stable" name used by callers of a function
                    instead of a generated name which would distinguish
                    different specialisations.

    NATIVE          Means that the class or function body details are not
                    accurate representations of the actual code and should not
                    be generated by a compiler.

    INTERCHANGEABLE Indicates that instances of a class are not sufficiently or
                    meaningfully distinguishable from each other with regard to
                    instantiation.

    SPECIAL         Indicates that the compiler should try and optimise calls to
                    the annotated function.

    ATOMIC          Indicates that the class and its instance(s) cannot store
                    attributes, although some may be predefined (such as the
                    __true__ method).

--------
NATIVE
"""

class boolean:
    """
    NATIVE
    INTERCHANGEABLE
    """
    def __true__(self):
        return self

    def __str__(self):
        if self:
            return "True"
        else:
            return "False"

class int:
    """
    NATIVE
    INTERCHANGEABLE
    """
    def __iadd__(self, other):
        """
        NAME: IMPL.builtins.int.__iadd__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __isub__(self, other):
        """
        NAME: IMPL.builtins.int.__isub__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __add__(self, other):
        """
        NAME: IMPL.builtins.int.__add__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __radd__(self, other):
        """
        NAME: IMPL.builtins.int.__radd__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __sub__(self, other):
        """
        NAME: IMPL.builtins.int.__sub__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __rsub__(self, other):
        """
        NAME: IMPL.builtins.int.__rsub__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __mul__(self, other):
        """
        NAME: IMPL.builtins.int.__mul__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __rmul__(self, other):
        """
        NAME: IMPL.builtins.int.__rmul__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __div__(self, other):
        """
        NAME: IMPL.builtins.int.__div__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __rdiv__(self, other):
        """
        NAME: IMPL.builtins.int.__rdiv__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __pow__(self, other):
        """
        NAME: IMPL.builtins.int.__pow__
        NATIVE
        """
        if isinstance(other, int):
            return int()
        else:
            TypeConstraintError

    def __lt__(self, other):
        """
        NAME: IMPL.builtins.int.__lt__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        else:
            TypeConstraintError

    def __gt__(self, other):
        """
        NAME: IMPL.builtins.int.__gt__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        else:
            TypeConstraintError

    def __le__(self, other):
        """
        NAME: IMPL.builtins.int.__le__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        else:
            TypeConstraintError

    def __ge__(self, other):
        """
        NAME: IMPL.builtins.int.__ge__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        else:
            TypeConstraintError

    def __eq__(self, other):
        """
        NAME: IMPL.builtins.int.__eq__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        else:
            TypeConstraintError

    def __ne__(self, other):
        """
        NAME: IMPL.builtins.int.__ne__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        else:
            TypeConstraintError

    def __neg__(self):
        """
        NAME: IMPL.builtins.int.__neg__
        NATIVE
        """
        return int()

    def __pos__(self):
        return self

    def __str__(self):
        """
        NAME: IMPL.builtins.int.__str__
        NATIVE
        """
        return string()

    def __true__(self):
        return self != 0

class long:
    """
    NATIVE
    INTERCHANGEABLE
    """
    def __iadd__(self, other):
        """
        NAME: IMPL.builtins.long.__iadd__
        NATIVE
        """
        if isinstance(other, int):
            return long()
        elif isinstance(other, long):
            return long()
        else:
            TypeConstraintError

    def __isub__(self, other):
        """
        NAME: IMPL.builtins.long.__isub__
        NATIVE
        """
        if isinstance(other, int):
            return long()
        elif isinstance(other, long):
            return long()
        else:
            TypeConstraintError

    def __add__(self, other):
        """
        NAME: IMPL.builtins.long.__add__
        NATIVE
        """
        if isinstance(other, int):
            return long()
        elif isinstance(other, long):
            return long()
        else:
            TypeConstraintError

    def __radd__(self, other):
        """
        NAME: IMPL.builtins.long.__radd__
        NATIVE
        """
        if isinstance(other, int):
            return long()
        elif isinstance(other, long):
            return long()
        else:
            TypeConstraintError

    def __sub__(self, other):
        """
        NAME: IMPL.builtins.long.__sub__
        NATIVE
        """
        if isinstance(other, int):
            return long()
        elif isinstance(other, long):
            return long()
        else:
            TypeConstraintError

    def __rsub__(self, other):
        """
        NAME: IMPL.builtins.long.__rsub__
        NATIVE
        """
        if isinstance(other, int):
            return long()
        elif isinstance(other, long):
            return long()
        else:
            TypeConstraintError

    def __lt__(self, other):
        """
        NAME: IMPL.builtins.long.__lt__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        else:
            TypeConstraintError

    def __gt__(self, other):
        """
        NAME: IMPL.builtins.long.__gt__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        else:
            TypeConstraintError

    def __le__(self, other):
        """
        NAME: IMPL.builtins.long.__le__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        else:
            TypeConstraintError

    def __ge__(self, other):
        """
        NAME: IMPL.builtins.long.__ge__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        else:
            TypeConstraintError

    def __eq__(self, other):
        """
        NAME: IMPL.builtins.long.__eq__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        else:
            TypeConstraintError

    def __ne__(self, other):
        """
        NAME: IMPL.builtins.long.__ne__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        else:
            TypeConstraintError

    def __neg__(self):
        """
        NAME: IMPL.builtins.long.__neg__
        NATIVE
        """
        return long()

    def __pos__(self):
        return self

    def __str__(self):
        """
        NAME: IMPL.builtins.long.__str__
        NATIVE
        """
        return string()

    def __true__(self):
        return self != 0

class float:
    """
    NATIVE
    INTERCHANGEABLE
    """
    def __iadd__(self, other):
        """
        NAME: IMPL.builtins.float.__iadd__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __isub__(self, other):
        """
        NAME: IMPL.builtins.float.__isub__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __add__(self, other):
        """
        NAME: IMPL.builtins.float.__add__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __radd__(self, other):
        """
        NAME: IMPL.builtins.float.__radd__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __sub__(self, other):
        """
        NAME: IMPL.builtins.float.__sub__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __rsub__(self, other):
        """
        NAME: IMPL.builtins.float.__rsub__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __mul__(self, other):
        """
        NAME: IMPL.builtins.float.__mul__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __rmul__(self, other):
        """
        NAME: IMPL.builtins.float.__rmul__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __div__(self, other):
        """
        NAME: IMPL.builtins.float.__div__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __rdiv__(self, other):
        """
        NAME: IMPL.builtins.float.__rdiv__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __pow__(self, other):
        """
        NAME: IMPL.builtins.float.__pow__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __rpow__(self, other):
        """
        NAME: IMPL.builtins.float.__rpow__
        NATIVE
        """
        if isinstance(other, int):
            return float()
        elif isinstance(other, long):
            return float()
        elif isinstance(other, float):
            return float()
        else:
            TypeConstraintError

    def __lt__(self, other):
        """
        NAME: IMPL.builtins.float.__lt__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        elif isinstance(other, float):
            return boolean()
        else:
            TypeConstraintError

    def __gt__(self, other):
        """
        NAME: IMPL.builtins.float.__gt__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        elif isinstance(other, float):
            return boolean()
        else:
            TypeConstraintError

    def __le__(self, other):
        """
        NAME: IMPL.builtins.float.__le__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        elif isinstance(other, float):
            return boolean()
        else:
            TypeConstraintError

    def __ge__(self, other):
        """
        NAME: IMPL.builtins.float.__ge__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        elif isinstance(other, float):
            return boolean()
        else:
            TypeConstraintError

    def __eq__(self, other):
        """
        NAME: IMPL.builtins.float.__eq__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        elif isinstance(other, float):
            return boolean()
        else:
            TypeConstraintError

    def __ne__(self, other):
        """
        NAME: IMPL.builtins.float.__ne__
        NATIVE
        """
        if isinstance(other, int):
            return boolean()
        elif isinstance(other, long):
            return boolean()
        elif isinstance(other, float):
            return boolean()
        else:
            TypeConstraintError

    def __neg__(self):
        """
        NAME: IMPL.builtins.float.__neg__
        NATIVE
        """
        return float()

    def __pos__(self):
        return self

    def __str__(self):
        """
        NAME: IMPL.builtins.float.__str__
        NATIVE
        """
        return string()

    def __true__(self):
        return self != 0

class string:
    """
    NATIVE
    INTERCHANGEABLE
    """
    def __add__(self, other):
        """
        NAME: IMPL.builtins.string.__add__
        NATIVE
        """
        if isinstance(other, string):
            return string()
        else:
            TypeConstraintError

    def __radd__(self, other):
        """
        NAME: IMPL.builtins.string.__radd__
        NATIVE
        """
        if isinstance(other, string):
            return string()
        else:
            TypeConstraintError

    def __len__(self):
        """
        NAME: IMPL.builtins.string.__len__
        NATIVE
        """
        return int()

    def __str__(self):
        return self

    def __true__(self):
        return self.__len__() != 0

    def join(self, l):
        total = 0
        first = 1
        self_len = self.__len__()
        for i in l:
            if not first:
                total += self_len
            total += len(str(i))
            first = 0
        b = buffer(total)
        first = 1
        for i in l:
            if not first:
                b.append(self)
            b.append(str(i))
            first = 0
        s = str(b)
        return s

class buffer:
    """
    NATIVE
    INTERCHANGEABLE
    """
    def __init__(self, size):
        """
        NAME: IMPL.builtins.buffer.__init__
        NATIVE
        """
        if not isinstance(size, int):
            TypeConstraintError

    def append(self, s):
        """
        NAME: IMPL.builtins.buffer.append
        NATIVE
        """
        if not isinstance(s, string):
            TypeConstraintError
        pass

    def __str__(self):
        """
        NAME: IMPL.builtins.buffer.__str__
        NATIVE
        """
        return string()

class list:
    def __init__(self):
        self.next = None
        self.last = self

    def __getitem__(self, index):
        i = 0
        n = self
        # NOTE: Support negative indices using last.
        while i < index and n.next is not None:
            n = n.next
            i += 1
        if n.next is not None:
            return n.value
        else:
            raise IndexError() # NOTE: Make this compliant with Python!

    def __setitem__(self, index, value):
        i = 0
        n = self
        # NOTE: Support negative indices using last.
        while i < index and n.next is not None:
            n = n.next
            i += 1
        if n.next is not None:
            n.value = value
        else:
            raise IndexError() # NOTE: Make this compliant with Python!

    def __getslice__(self, start, end=None):
        slice = []
        i = 0
        n = self
        # NOTE: Support negative indices using last.
        while (end is None or i < end) and n.next is not None:
            if i >= start:
                slice.append(n.value)
            n = n.next
            i += 1
        return slice

    def __setslice__(self, start, end, slice):
        i = 0
        n = self
        j = 0
        p = slice
        # NOTE: Support negative indices using last.
        # NOTE: Support appending when start >= len(self).
        while i < end and n is not None and p is not None:
            if i >= start:
                n.value = p.value
                p = p.next
                j += 1
            n = n.next
            i += 1

    def append(self, value):
        n = self.last
        n.value = value
        n.next = self.__class__()
        self.last = n.next

    def __len__(self):
        i = 0
        n = self
        while n.next is not None:
            n = n.next
            i += 1
        return i

    def __add__(self, other):
        result = self.__class__()
        for value in self:
            result.append(value)
        for value in other:
            result.append(value)
        return result

    def __str__(self):
        output = ["["]
        n = self
        first = 1
        while n.next is not None:
            if not first:
                output.append(", ")
            else:
                first = 0
            output.append(str(n.value))
            n = n.next
        output.append("]")
        return "".join(output)

    def __iter__(self):
        return listiterator(self)

    def __true__(self):
        return self.__len__() != 0

class listiterator:
    def __init__(self, l):
        self.l = l

    def next(self):
        l = self.l
        next = l.next
        if next is not None:
            self.l = next
            return l.value
        else:
            raise StopIteration() # NOTE: Make this compliant with Python!

    def __true__(self):
        """
        NAME: IMPL.builtins.int.__true__
        NATIVE
        """
        return boolean()

class tuple:
    def __init__(self):
        self.next = None
        self.last = self

    def __getitem__(self, index):
        i = 0
        n = self
        # NOTE: Support negative indices using last.
        while i < index and n.next is not None:
            n = n.next
            i += 1
        if n.next is not None:
            return n.value
        else:
            raise IndexError() # NOTE: Make this compliant with Python!

    def __getslice__(self, start, end=None):
        # NOTE: Should probably return a tuple.
        slice = []
        i = 0
        n = self
        # NOTE: Support negative indices using last.
        while (end is None or i < end) and n.next is not None:
            if i >= start:
                slice.append(n.value)
            n = n.next
            i += 1
        return slice

    # NOTE: The append method should be internal at most.

    def append(self, value):
        n = self.last
        n.value = value
        n.next = self.__class__()
        self.last = n.next

    def __len__(self):
        i = 0
        n = self
        while n.next is not None:
            n = n.next
            i += 1
        return i

    def __add__(self, other):
        result = self.__class__()
        for value in self:
            result.append(value)
        for value in other:
            result.append(value)
        return result

    def __str__(self):
        output = ["("]
        n = self
        first = 1
        while n.next is not None:
            if not first:
                output.append(", ")
            else:
                first = 0
            output.append(str(n.value))
            n = n.next
        output.append(")")
        return "".join(output)

    def __iter__(self):
        return tupleiterator(self)

    def __true__(self):
        return self.__len__() != 0

class tupleiterator:
    def __init__(self, l):
        self.l = l

    def next(self):
        l = self.l
        next = l.next
        if next is not None:
            self.l = next
            return l.value
        else:
            raise StopIteration() # NOTE: Make this compliant with Python!

    def __true__(self):
        """
        NAME: IMPL.builtins.int.__true__
        NATIVE
        """
        return boolean()

class Exception:
    pass

class StopIteration(Exception):
    pass

class IndexError(Exception):
    pass

class AttributeError(Exception):
    pass

class TypeError(Exception):
    pass

class none:
    """
    NATIVE
    INTERCHANGEABLE
    ATOMIC
    """
    def __true__(self):
        return False

    def __str__(self):
        return "None"

class undefined:
    """
    NATIVE
    INTERCHANGEABLE
    ATOMIC
    """
    pass

def isinstance(obj, cls):
    """
    NAME: IMPL.builtins.isinstance
    NATIVE
    SPECIAL
    """
    return boolean()

def issubclass(cls1, cls2):
    """
    NAME: IMPL.builtins.isinstance
    NATIVE
    SPECIAL
    """
    return boolean()

def len(x):
    return x.__len__()

def max(*l):
    max_so_far = l[0]
    for i in l[1:]:
        if i > max_so_far:
            max_so_far = i
    return max_so_far

def str(x):
    return x.__str__()

def raw_input(prompt=''):
    return string()

class xrange:
    def __init__(self, start, end, step=1):
        self.start = start
        self.end = end
        self.step = step
        self.current = start

    def __iter__(self):
        return self

    def next(self):
        if self.current >= self.end:
            raise StopIteration()
        current = self.current
        self.current += self.step
        return current

# Special values. None of these definitions should be generated by the compiler.
# All such definitions should be made in the underlying implementation.

True = boolean()
False = boolean()
None = none()
Undefined = undefined()

# Special functions. These all operate on references at run-time.

def __is__(a, b):
    """
    NAME: IMPL.builtins.__is__
    NATIVE
    """
    return boolean()

def __is_not__(a, b):
    """
    NAME: IMPL.builtins.__is_not__
    NATIVE
    """
    return boolean()

def __not__(a):
    """
    NAME: IMPL.builtins.__not__
    NATIVE
    """
    return boolean()

# builtin vars

__name__ = string()

class object:
    pass

class dict:
    def __init__(self, *args, **kwargs):
        pass

    def update(self, *args, **kwargs):
        pass

# vim: tabstop=4 expandtab shiftwidth=4
